package com.founder.bdyx.wxpay.controller.wxpay;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.founder.bdyx.wxpay.mapper.PayNoticeInfoMapper;
import com.founder.bdyx.modules.sys.model.ApplyInfo;
import com.founder.bdyx.wxpay.mapper.ProfitSharingModelResponseMapper;
import com.founder.bdyx.wxpay.model.PayNoticeInfo;
import com.founder.bdyx.modules.sys.service.ApplyInfoService;
import com.founder.bdyx.wxpay.domain.ResponseInfo;
import com.founder.bdyx.wxpay.domain.WxApiSharingType;
import com.founder.bdyx.wxpay.domain.WxPayV3Bean;
import com.founder.bdyx.wxpay.model.ProfitSharingModel;
import com.founder.bdyx.wxpay.model.ProfitSharingModelResponse;
import com.founder.bdyx.wxpay.model.Receiver;
import com.founder.bdyx.wxpay.service.WxPayV3Service;
import com.founder.bdyx.wxpay.utils.CommonUtil;
import com.ijpay.core.IJPayHttpResponse;
import com.ijpay.core.enums.RequestMethod;
import com.ijpay.core.kit.AesUtil;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.PayKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.core.utils.DateTimeZoneUtil;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.enums.WxApiType;
import com.ijpay.wxpay.enums.WxDomain;
import com.ijpay.wxpay.model.v3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.*;

/**
 * @ClassName MainController
 * @Description TODO
 * @Author ZhangYong
 * @Date 2020/8/31 10:08
 * @Version 1.0
 **/
@Controller
@RequestMapping("/v3")
public class WxPayV3Controller {

    private static final Logger log = LoggerFactory.getLogger(WxPayV3Controller.class);

    @Resource
    WxPayV3Bean wxPayV3Bean;
    @Autowired
    ApplyInfoService applyInfoService;
    @Autowired
    PayNoticeInfoMapper payNoticeInfoMapper;
    @Autowired
    WxPayV3Service wxPayV3Service;
    String platSerialNo;

    //nativePay 直连商户模式
    @RequestMapping("/nativePay")
    @ResponseBody
    public String nativePay() {
        try {
            String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 60);//支付有效时间
            UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
                    .setAppid(wxPayV3Bean.getAppId())
                    .setMchid(wxPayV3Bean.getMchId())
                    .setDescription("直连nativePay测试支付")
                    .setOut_trade_no(PayKit.generateStr())
                    .setTime_expire(timeExpire)
                    .setAttach("微信系开发脚手架 https://gitee.com/javen205/TNWX")
                    .setNotify_url(wxPayV3Bean.getDomain().concat("/v3/payNotify"))
                    .setAmount(new Amount().setTotal(1));

            log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiType.NATIVE_PAY.toString(),
                    wxPayV3Bean.getMchId(),
                    wxPayV3Service.getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    JSONUtil.toJsonStr(unifiedOrderModel)
            );
            log.info("统一下单响应 {}", response);
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            return response.getBody();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //jsApiPay 直连商户模式
    @RequestMapping("/jsApiPay")
    @ResponseBody
    public String jsApiPay(@RequestParam(value = "openId", required = false, defaultValue = "opnHy5vL7sTgadH7b4wVSnhsZejc") String openId) {
        try {
            log.info("直连jsApi支付被调用,openId={}",openId);
            String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
            UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
                    .setAppid(wxPayV3Bean.getAppId())
                    .setMchid(wxPayV3Bean.getMchId())
                    .setDescription("IJPay 让支付触手可及")
                    .setOut_trade_no(PayKit.generateStr())
                    .setTime_expire(timeExpire)
                    .setAttach("微信系开发脚手架 https://gitee.com/javen205/TNWX")
                    .setNotify_url(wxPayV3Bean.getDomain().concat("/v3/payNotify"))
                    .setAmount(new Amount().setTotal(3))
                    .setPayer(new Payer().setOpenid(openId));

            log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiType.JS_API_PAY.toString(),
                    wxPayV3Bean.getMchId(),
                    wxPayV3Service.getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    JSONUtil.toJsonStr(unifiedOrderModel)
            );
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            log.info("统一下单响应 {}", response);
            if (verifySignature) {
                String body = response.getBody();
                JSONObject jsonObject = JSONUtil.parseObj(body);
                String prepayId = jsonObject.getStr("prepay_id");
                Map<String, String> map = WxPayKit.jsApiCreateSign(wxPayV3Bean.getAppId(), prepayId, wxPayV3Bean.getKeyPath());
                log.info("唤起支付参数:{}", map);
                return JSONUtil.toJsonStr(map);
            }
            return response.getBody();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //h5支付 直连商户模式
    @RequestMapping("/h5Pay")
    @ResponseBody
    public ResponseInfo h5Pay(HttpServletRequest request) {
        try {
            String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
            H5Info h5Info = new H5Info()
                    .setType("Wap");//场景类型示例值：iOS, Android, Wap
            SceneInfo sceneInfo = new SceneInfo()
                    .setPayer_client_ip(CommonUtil.getIpAddress(request))//调用微信支付API的机器IP，支持IPv4和IPv6两种格式的IP地址。
                    .setH5_info(h5Info);
            UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
                    .setAppid(wxPayV3Bean.getAppId())//公众号ID
                    .setMchid(wxPayV3Bean.getMchId())//直连商户号
                    .setDescription("IJPay 让支付触手可及")//商品描述
                    .setOut_trade_no(PayKit.generateStr())//商户订单号
                    .setTime_expire(timeExpire)//订单失效时间
                    .setAttach("微信系开发脚手架 https://gitee.com/javen205/TNWX")//附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用
                    .setNotify_url(wxPayV3Bean.getDomain().concat("/v3/payNotify"))//通知地址
                    .setAmount(new Amount().setTotal(1))//订单总金额，单位为分。
                    .setScene_info(sceneInfo);//支付场景描述

            log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiType.H5_PAY.toString(),
                    wxPayV3Bean.getMchId(),
                    wxPayV3Service.getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    JSONUtil.toJsonStr(unifiedOrderModel)
            );
            log.info("统一下单响应 {}", response);
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            return new ResponseInfo(response.getBody());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResponseInfo(500,"null",null);
    }

    //nativePay 服务商模式
    @RequestMapping("/nativeServicePay")
    @ResponseBody
    public String nativeServicePay() {
        try {
            String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
            UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
                    .setSp_appid(wxPayV3Bean.getAppId())
                    .setSp_mchid(wxPayV3Bean.getMchId())
                    .setSub_mchid("1602232807")
                    .setDescription("支付测试")
                    .setOut_trade_no(PayKit.generateStr())
                    .setTime_expire(timeExpire)
                    .setAttach("微信系开发脚手架 https://gitee.com/javen205/TNWX")
                    .setNotify_url(wxPayV3Bean.getDomain().concat("/v3/payNotify"))
                    .setAmount(new Amount().setTotal(1));

            log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiType.PARTNER_NATIVE_PAY.toString(),
                    wxPayV3Bean.getMchId(),
                    wxPayV3Service.getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    JSONUtil.toJsonStr(unifiedOrderModel)
            );
            log.info("统一下单响应 {}", response);
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            return response.getBody();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //jsApiPay 服务商模式
    @RequestMapping("/jsApiServicePay")
    @ResponseBody
    public String jsApiServicePay(@RequestParam(value = "openId", required = false, defaultValue = "o-_-itxuXeGW3O1cxJ7FXNmq8Wf8") String openId) {
        try {
            String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 60);
            UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
                    .setSp_appid(wxPayV3Bean.getAppId())
                    .setSp_mchid(wxPayV3Bean.getMchId())
                    .setSub_mchid("1602232807")
                    .setDescription("jsApi测试支付(服务商模式)")
                    .setOut_trade_no(PayKit.generateStr())
                    .setTime_expire(timeExpire)
                    .setAttach("微信系开发脚手架 https://gitee.com/javen205/TNWX")
                    .setNotify_url(wxPayV3Bean.getDomain().concat("/v3/payNotify"))
                    .setAmount(new Amount().setTotal(1))
                    .setPayer(new Payer().setSp_openid(openId));

            log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiType.PARTNER_JS_API_PAY.toString(),
                    wxPayV3Bean.getMchId(),
                    wxPayV3Service.getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    JSONUtil.toJsonStr(unifiedOrderModel)
            );
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            log.info("统一下单响应 {}", response);

            if (verifySignature) {
                String body = response.getBody();
                JSONObject jsonObject = JSONUtil.parseObj(body);
                String prepayId = jsonObject.getStr("prepay_id");
                Map<String, String> map = WxPayKit.jsApiCreateSign(wxPayV3Bean.getAppId(), prepayId, wxPayV3Bean.getKeyPath());
                log.info("唤起支付参数:{}", map);
                return JSONUtil.toJsonStr(map);
            }
            return response.getBody();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //h5支付 服务商模式
    @RequestMapping("/h5ServerPay")
    @ResponseBody
    public ResponseInfo h5ServerPay() {
        try {
            String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
            H5Info h5Info = new H5Info()
                    .setType("Wap");
            SceneInfo sceneInfo = new SceneInfo()
                    .setPayer_client_ip("183.69.223.88")
                    .setH5_info(h5Info);
            UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
                    .setSp_appid(wxPayV3Bean.getAppId())
                    .setSp_mchid(wxPayV3Bean.getMchId())
                    .setSub_mchid("1602232807")
                    .setDescription("IJPay 让支付触手可及")
                    .setOut_trade_no(PayKit.generateStr())
                    .setTime_expire(timeExpire)
                    .setAttach("微信系开发脚手架 https://gitee.com/javen205/TNWX")
                    .setNotify_url(wxPayV3Bean.getDomain().concat("/v3/payNotify"))
                    .setAmount(new Amount().setTotal(1)).setScene_info(sceneInfo);

            log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiType.PARTNER_H5_PAY.toString(),
                    wxPayV3Bean.getMchId(),
                    wxPayV3Service.getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    JSONUtil.toJsonStr(unifiedOrderModel)
            );
            log.info("统一下单响应 {}", response);
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            return new ResponseInfo(response.getBody());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResponseInfo(500,"null",null);
    }

    /**
     * 获取平台证书列表
     * @Author ZhangYong
     * @Date 10:44 2020/11/10
     * @Param []
     * @return java.lang.String
     **/
    @RequestMapping("/get")
    @ResponseBody
    public String v3Get() {
        // 获取平台证书列表
        try {
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.GET,
                    WxDomain.CHINA.toString(),
                    WxApiType.GET_CERTIFICATES.toString(),
                    wxPayV3Bean.getMchId(),
                    wxPayV3Service.getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    ""
            );

            String timestamp = response.getHeader("Wechatpay-Timestamp");
            String nonceStr = response.getHeader("Wechatpay-Nonce");
            String serialNumber = response.getHeader("Wechatpay-Serial");
            String signature = response.getHeader("Wechatpay-Signature");

            String body = response.getBody();
            int status = response.getStatus();

            log.info("serialNumber: {}", serialNumber);
            log.info("status: {}", status);
            log.info("body: {}", body);
            int isOk = 200;
            if (status == isOk) {
                JSONObject jsonObject = JSONUtil.parseObj(body);
                JSONArray dataArray = jsonObject.getJSONArray("data");
                // 默认认为只有一个平台证书
                JSONObject encryptObject = dataArray.getJSONObject(0);
                JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");
                String associatedData = encryptCertificate.getStr("associated_data");
                String cipherText = encryptCertificate.getStr("ciphertext");
                String nonce = encryptCertificate.getStr("nonce");
                String serialNo = encryptObject.getStr("serial_no");
                final String platSerialNo = savePlatformCert(associatedData, nonce, cipherText, wxPayV3Bean.getPlatformCertPath());
                log.info("平台证书序列号: {} serialNo: {}", platSerialNo, serialNo);
            }
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            System.out.println("verifySignature:" + verifySignature);
            return body;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private String savePlatformCert(String associatedData, String nonce, String cipherText, String certPath) {
        try {
            AesUtil aesUtil = new AesUtil(wxPayV3Bean.getApiKey3().getBytes(StandardCharsets.UTF_8));
            // 平台证书密文解密
            // encrypt_certificate 中的  associated_data nonce  ciphertext
            String publicKey = aesUtil.decryptToString(
                    associatedData.getBytes(StandardCharsets.UTF_8),
                    nonce.getBytes(StandardCharsets.UTF_8),
                    cipherText
            );
            // 保存证书
            FileWriter writer = new FileWriter(certPath);
            writer.write(publicKey);
            // 获取平台证书序列号
            X509Certificate certificate = PayKit.getCertificate(new ByteArrayInputStream(publicKey.getBytes()));
            return certificate.getSerialNumber().toString(16).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping(value = "/payNotify", method = {org.springframework.web.bind.annotation.RequestMethod.POST, org.springframework.web.bind.annotation.RequestMethod.GET})
    @ResponseBody
    public void payNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("收到支付成功的通知");
        response.setHeader("Content-type", ContentType.JSON.toString());
        Map<String, String> map = new HashMap<>(12);
        try {
            String timestamp = request.getHeader("Wechatpay-Timestamp");
            String nonce = request.getHeader("Wechatpay-Nonce");
            String serialNo = request.getHeader("Wechatpay-Serial");
            String signature = request.getHeader("Wechatpay-Signature");

            log.info("timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);
            String result = HttpKit.readData(request);
            log.info("支付通知密文 {}", result);

            // 需要通过证书序列号查找对应的证书，verifyNotify 中有验证证书的序列号
            String plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp,
                    wxPayV3Bean.getApiKey3(), wxPayV3Bean.getPlatformCertPath());

            log.info("支付通知明文 {}", plainText);

            if(StrUtil.isEmpty(plainText)){
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "签名错误");
                response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
                response.flushBuffer();
                return;
            }

            /*支付通知记录保存 pay_notice_info*/
            PayNoticeInfo payNoticeInfo = JSONUtil.toBean(plainText, PayNoticeInfo.class);
            payNoticeInfo.setPayer_total(payNoticeInfo.getAmount().getTotal());
            payNoticeInfoMapper.savePayNoticeInfo(payNoticeInfo);
            if("SUCCESS".equals(payNoticeInfo.getTrade_state())) {

                ApplyInfo applyInfo = applyInfoService.getByAppId(payNoticeInfo.getOut_trade_no());
                if(applyInfo!=null && !"2".equals(applyInfo.getPayStatus())){//未支付状态
                    applyInfo.setPayStatus("2");
                    applyInfo.setPayTime(new Date());
                    applyInfo.setSharingFlag("NOT");
                    applyInfoService.updateApplyInfo(applyInfo);
                }

                /*请求分账  */
                wxPayV3Service.profitShareRequest(payNoticeInfo);
            }

            response.setStatus(200);
            map.put("code", "SUCCESS");
            map.put("message", "SUCCESS");
            response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
            response.flushBuffer();
        } catch (Exception e) {
            log.error("支付结果通知api处理异常",e);
        }
    }

    /**
     * JSAPI下单
     * @param openid 用户openid
     * @param uuid   订单id
     * @return
     */
    @RequestMapping("/orderPay")
    public ModelAndView orderPay(@RequestParam(value = "openid", required = true) String openid, @RequestParam(value = "uuid", required = true) String uuid){
        String retStr = "";
        ModelAndView m = new ModelAndView();
        m.setViewName("/wxpay/jsApiPay");
        try {
            log.info("直连jsApi支付被调用,openId={},uuid={}",openid, uuid);
            ApplyInfo applyInfo = applyInfoService.getByAppId(uuid);
            if(applyInfo == null || !openid.equals(applyInfo.getUserId())){
                ResponseInfo info = new ResponseInfo(-1,"订单异常",null);
                retStr = JSONUtil.toJsonStr(info);
                m.addObject("retStr",retStr);
                return m;
            }
            String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 60 * 2);
            int payPrice = (int) (applyInfo.getPayPrice() * 100);
            UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
                    .setAppid(wxPayV3Bean.getAppId())
                    .setMchid(wxPayV3Bean.getMchId())
                    .setDescription("病历档案")
                    .setOut_trade_no(uuid)
                    .setTime_expire(timeExpire)
                    .setAttach("attach_info")
                    .setNotify_url(wxPayV3Bean.getDomain().concat("/v3/payNotify"))
                    .setAmount(new Amount().setTotal(payPrice))
                    .setPayer(new Payer().setOpenid(openid))
                    .setSettle_info(new SettleInfo().setProfit_sharing(true));

            log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
            JSONObject jsonObject1 = JSONUtil.parseObj(unifiedOrderModel);
            jsonObject1.getJSONObject("settle_info").remove("subsidy_amount");
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiType.JS_API_PAY.toString(),
                    wxPayV3Bean.getMchId(),
                    wxPayV3Service.getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    JSONUtil.toJsonStr(jsonObject1)
            );
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            log.info("统一下单响应 {}", response);
            if (verifySignature) {
                /*如果prepay_id为空  则为异常下单情况  返回实际参数 例如订单已支付*/
                if(response.getStatus() != 200) {
                    if(applyInfo.getPrepayId() != null){
                        Map<String, String> map = WxPayKit.jsApiCreateSign(wxPayV3Bean.getAppId(), applyInfo.getPrepayId(), wxPayV3Bean.getKeyPath());
                        log.info("唤起支付参数:{}", map);
                        retStr = JSONUtil.toJsonStr(map);
                        m.addObject("retStr",retStr);
                        return m;
                    }
                    retStr = response.getBody();
                }else{
                    String body = response.getBody();
                    JSONObject jsonObject = JSONUtil.parseObj(body);
                    String prepayId = jsonObject.getStr("prepay_id");

                    applyInfo.setPrepayId(prepayId);
                    applyInfoService.updatePrepayId(applyInfo);
                    Map<String, String> map = WxPayKit.jsApiCreateSign(wxPayV3Bean.getAppId(), prepayId, wxPayV3Bean.getKeyPath());
                    log.info("唤起支付参数:{}", map);
                    retStr = JSONUtil.toJsonStr(map);
                }
            }else {
                retStr = response.getBody();
            }
        } catch (Exception e) {
            log.error("统一下单api接口调用失败",e);
            ResponseInfo info = new ResponseInfo(-1,e.getMessage(),null);
            retStr = JSONUtil.toJsonStr(info);
        }

        m.addObject("retStr",retStr);
        return m;
    }
    /*@RequestMapping(value="/orderPay",produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public String orderPay(@RequestParam(value = "openid", required = true) String openid, @RequestParam(value = "uuid", required = true) String uuid) {
        try {
            log.info("直连jsApi支付被调用,openId={},uuid={}",openid, uuid);
            ApplyInfo applyInfo = applyInfoService.getByAppId(uuid);
            if(applyInfo == null || !openid.equals(applyInfo.getUserId())){
                ResponseInfo info = new ResponseInfo(-1,"订单异常",null);
                return JSONUtil.toJsonStr(info);
            }
            String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 60 * 2);
            int payPrice = (int) (applyInfo.getPayPrice() * 100);
            UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
                    .setAppid(wxPayV3Bean.getAppId())
                    .setMchid(wxPayV3Bean.getMchId())
                    .setDescription("病历档案")
                    .setOut_trade_no(uuid)
                    .setTime_expire(timeExpire)
                    .setAttach("微信系开发脚手架 https://gitee.com/javen205/TNWX")
                    .setNotify_url(wxPayV3Bean.getDomain().concat("/v3/payNotify"))
                    .setAmount(new Amount().setTotal(payPrice))
                    .setPayer(new Payer().setOpenid(openid))
                    .setSettle_info(new SettleInfo().setProfit_sharing(true));

            log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
            JSONObject jsonObject1 = JSONUtil.parseObj(unifiedOrderModel);
            jsonObject1.getJSONObject("settle_info").remove("subsidy_amount");
            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.POST,
                    WxDomain.CHINA.toString(),
                    WxApiType.JS_API_PAY.toString(),
                    wxPayV3Bean.getMchId(),
                    wxPayV3Service.getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    JSONUtil.toJsonStr(jsonObject1)
            );
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            log.info("统一下单响应 {}", response);
            if (verifySignature) {
                *//*如果prepay_id为空  则为异常下单情况  返回实际参数 例如订单已支付*//*
                if(response.getStatus() != 200) return response.getBody();

                String body = response.getBody();
                JSONObject jsonObject = JSONUtil.parseObj(body);
                String prepayId = jsonObject.getStr("prepay_id");

                applyInfo.setPrepayId(prepayId);
                applyInfoService.updatePrepayId(applyInfo);
                Map<String, String> map = WxPayKit.jsApiCreateSign(wxPayV3Bean.getAppId(), prepayId, wxPayV3Bean.getKeyPath());
                log.info("唤起支付参数:{}", map);
                return JSONUtil.toJsonStr(map);
            }
            return response.getBody();
        } catch (Exception e) {
            log.error("统一下单api接口调用失败",e);
        }
        return null;
    }*/

    @RequestMapping("/orderQuery")
    @ResponseBody
    public String orderQuery(@RequestParam(value = "uuid", required = true) String uuid){
        try {
            log.info("查询订单被调用,uuid={}",uuid);

            IJPayHttpResponse response = WxPayApi.v3(
                    RequestMethod.GET,
                    WxDomain.CHINA.toString(),
                    String.format(WxApiType.ORDER_QUERY_BY_NO.getType(),uuid).concat("?mchid="+wxPayV3Bean.getMchId()),
                    wxPayV3Bean.getMchId(),
                    wxPayV3Service.getSerialNumber(),
                    null,
                    wxPayV3Bean.getKeyPath(),
                    ""
            );
            // 根据证书序列号查询对应的证书来验证签名结果
            boolean verifySignature = WxPayKit.verifySignature(response, wxPayV3Bean.getPlatformCertPath());
            log.info("verifySignature: {}", verifySignature);
            log.info("查询订单响应 {}", response);
            if (verifySignature) {
                if(response.getStatus() != 200) return response.getBody();

                String body = response.getBody();
                JSONObject jsonObject = JSONUtil.parseObj(body);
                return jsonObject.toString();
            }
            return response.getBody();
        } catch (Exception e) {
            log.error("查询订单api接口调用失败",e);
        }
        return null;
    }

    @RequestMapping("/test1")
    @ResponseBody
    public String test1(){
        List<PayNoticeInfo> al = payNoticeInfoMapper.getAllToShare("NOT");

        for (PayNoticeInfo info :
                al) {
            wxPayV3Service.profitShareRequest(info);
        }
        return "";
    }

    @RequestMapping("/test2")
    @ResponseBody
    public String test2(){
        List<PayNoticeInfo> al = payNoticeInfoMapper.getAllToShare("PROCESSING");

        for (PayNoticeInfo info :
                al) {
            wxPayV3Service.profitShareResult(info);
        }
        return "";
    }

    @RequestMapping("/test3")
    @ResponseBody
    public String test3(){
        List<PayNoticeInfo> al = payNoticeInfoMapper.getAllToShare("FINISHED");

        for (PayNoticeInfo info :
                al) {
            wxPayV3Service.profitShareUnfreeze(info);
        }
        return "";
    }
}
